Skip to content

MOSU-320 feat: 제휴업체 신청 완료 알림톡 템플릿 추가#321

Merged
polyglot-k merged 7 commits intodevelopfrom
feature/mosu-320
Aug 12, 2025
Merged

MOSU-320 feat: 제휴업체 신청 완료 알림톡 템플릿 추가#321
polyglot-k merged 7 commits intodevelopfrom
feature/mosu-320

Conversation

@chominju02
Copy link
Contributor

@chominju02 chominju02 commented Aug 11, 2025

✨ 구현한 기능

📢 논의하고 싶은 내용

🎸 기타

Summary by CodeRabbit

  • New Features
    • Added guest notifications for exam application completion via AlimTalk and SMS.
    • Messages include payment reference, exam date, school name, lunch choice, an exam reminder, and a safety notice link.
    • Content and delivery align with existing member notifications to ensure consistent messaging and timely updates for guest applicants.

@chominju02 chominju02 self-assigned this Aug 11, 2025
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @chominju02, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 모의수능 신청 완료 시 발송되는 알림톡 및 SMS 메시지 템플릿을 추가합니다. 이는 사용자가 신청한 모의수능에 대한 결제 번호, 응시 일자, 시험 장소, 도시락 여부 등의 상세 정보를 포함하여 신청 완료를 정확하게 안내하기 위함입니다.

Highlights

  • 알림톡 템플릿 추가: 모의수능 신청 완료 시 발송될 새로운 알림톡 템플릿(notify.exam.guest.application.complete.alimtalk)을 추가했습니다.
  • SMS 템플릿 추가: 모의수능 신청 완료 시 발송될 새로운 SMS 템플릿(notify.exam.guest.application.complete.sms)을 추가했습니다.
  • 동적 정보 포함: 추가된 템플릿들은 결제 번호, 응시 일자, 시험 장소, 도시락 여부 등 신청 관련 동적 정보를 포함합니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

안녕하세요. PR을 리뷰했습니다. 제휴업체 신청이 아닌 비회원 모의수능 신청 완료 알림톡 템플릿을 추가하는 것으로 보입니다. PR 제목을 실제 변경 내용에 맞게 수정하는 것을 권장합니다. 코드 변경 자체는 좋아 보이며, 메시지 포맷의 일관성을 위한 작은 제안 한 가지를 남깁니다.

@coderabbitai
Copy link

coderabbitai bot commented Aug 11, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds guest-specific notification support for exam application completion: new message templates, a guest notify request DTO, a new notification status/template code, wiring into notification sender and variable factory, and switching deposit event to emit the guest notification status.

Changes

Cohort / File(s) Summary
Message templates
src/main/resources/messages_ko.properties
Added notify.exam.guest.application.complete.alimtalk and notify.exam.guest.application.complete.sms entries mirroring existing application completion templates with placeholders (paymentKey, examDate, schoolName, lunch) and warning link.
Notify variable factory
src/main/java/.../application/notify/NotifyVariableFactory.java
Added handling for APPLICATION_GUEST_SUCCESS, routes to new helper that builds guest notification variables from repository projection.
New DTO / variables
src/main/java/.../application/notify/dto/ApplicationGuestNotifyRequest.java
New public record ApplicationGuestNotifyRequest implementing LunaNotificationVariable, with factory from(ExamApplicationNotifyProjection), toMap(), and getNotificationButtonUrls().
Deposit event -> guest status
src/main/java/.../virtualaccount/event/DepositSuccessEventHandler.java
Changed emitted notification status from APPLICATION_SUCCESS to APPLICATION_GUEST_SUCCESS for deposit handling path (logic otherwise unchanged).
Notification sender mapping
src/main/java/.../infra/notify/component/luna/LunaNotifyWithSmsFallbackSender.java
Included APPLICATION_GUEST_SUCCESS in notify strategy mapping (static import added) so sender recognizes guest status.
Notification status enum
src/main/java/.../infra/notify/dto/luna/LunaNotificationStatus.java
Added enum constant APPLICATION_GUEST_SUCCESS("게스트 신청 완료", LunaNotifyTemplateCode.APPLICATION_GUEST).
Template code enum
src/main/java/.../infra/notify/dto/luna/LunaNotifyTemplateCode.java
Added enum constant APPLICATION_GUEST with id 50051 and template keys for AlimTalk and SMS (notify.exam.guest.application.complete.alimtalk, notify.exam.guest.application.complete.sms).

Sequence Diagram(s)

sequenceDiagram
    participant DepositSvc as DepositSuccessEventHandler
    participant Repo as ExamApplicationRepository
    participant Factory as NotifyVariableFactory
    participant Luna as LunaNotifyWithSmsFallbackSender
    participant LunaSvc as LunaNotificationService

    DepositSvc->>LunaSvc: create LunaNotificationEvent(status=APPLICATION_GUEST_SUCCESS, targetId)
    LunaSvc->>Factory: resolve variables for APPLICATION_GUEST_SUCCESS(targetId)
    Factory->>Repo: fetch ExamApplicationNotifyProjection(targetId)
    Repo-->>Factory: ExamApplicationNotifyProjection
    Factory-->>LunaSvc: ApplicationGuestNotifyRequest (variables)
    LunaSvc->>Luna: send notification (template APPLICATION_GUEST -> AlimTalk/SMS)
    Luna-->>LunaSvc: delivery result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Possibly related PRs

Poem

I hop with a note for guests tonight,
Two bright templates, AlimTalk and SMS light.
Dates and lunches tucked in neat rows,
Payment keys wink where the warning page glows.
A rabbit's small cheer — guest alerts take flight! 🥕🐇

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/mosu-320

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/main/resources/messages_ko.properties (1)

33-33: Remove extra space before colon in “바로가기 :”

-유의사항 바로가기 : https://www.mosuedu.com/warning
+유의사항 바로가기: https://www.mosuedu.com/warning
🧹 Nitpick comments (2)
src/main/resources/messages_ko.properties (2)

19-25: Comma spacing consistency (전, …)

Elsewhere in this file, there’s no space after the comma in “전,”. Align this line to match for consistency.

-시험 1주일 전, 시험 관련 유의사항과 수험표 안내 리마인드 알림이 발송될 예정입니다.
+시험 1주일 전,시험 관련 유의사항과 수험표 안내 리마인드 알림이 발송될 예정입니다.

32-32: Comma spacing consistency (전, …)

Same nitpick here: remove the space after the comma.

-시험 1주일 전, 시험 관련 유의사항과 수험표 안내 리마인드 알림이 발송될 예정입니다.\n\n\
+시험 1주일 전,시험 관련 유의사항과 수험표 안내 리마인드 알림이 발송될 예정입니다.\n\n\
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ba9584e and 9031145.

📒 Files selected for processing (1)
  • src/main/resources/messages_ko.properties (1 hunks)

@polyglot-k polyglot-k self-assigned this Aug 12, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/main/java/life/mosu/mosuserver/application/notify/dto/ApplicationGuestNotifyRequest.java (3)

31-33: Use a human-readable button label instead of the URL

Using the URL string for both label and URL will render an unfriendly label. Prefer a descriptive label.

Apply:

-        return LunaNotificationButtonUrls.of(
-                NotificationButtonUrl.of(WARNING_PAGE, WARNING_PAGE)
-        );
+        return LunaNotificationButtonUrls.of(
+                NotificationButtonUrl.of("유의사항 확인", WARNING_PAGE)
+        );

40-41: Confirm date format expected by templates; consider explicit formatter

ISO date via LocalDate.toString() may not match the desired user-facing format.

Apply:

-                "examDate", examDate.toString(),
+                "examDate", examDate.format(DATE_FORMAT),

Add the following outside this hunk:

import java.time.format.DateTimeFormatter;

// inside record (static field)
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy.MM.dd");

23-27: Harden lunch mapping against null/blank lunch names

If lunch is checked but lunchName is null/blank, the template will get a null or empty value. Default to "선택 안 함" in that case.

Apply:

-        return new ApplicationGuestNotifyRequest(examApplication.paymentKey(),
-                examApplication.examDate(), examApplication.schoolName(),
-                examApplication.isLunchChecked() ? examApplication.lunchName()
-                        : "선택 안 함");
+        String lunch = (examApplication.isLunchChecked()
+                && examApplication.lunchName() != null
+                && !examApplication.lunchName().isBlank())
+                ? examApplication.lunchName()
+                : "선택 안 함";
+        return new ApplicationGuestNotifyRequest(
+                examApplication.paymentKey(),
+                examApplication.examDate(),
+                examApplication.schoolName(),
+                lunch
+        );
src/main/java/life/mosu/mosuserver/application/notify/NotifyVariableFactory.java (1)

87-93: Reduce duplication between application and guest variable builders

Both methods fetch the same projection with identical error handling. Extract a shared helper to keep DRY.

Apply within this method:

-        ExamApplicationNotifyProjection projection = examApplicationRepository.findExamAndPaymentByExamApplicationId(
-                        targetId)
-                .orElseThrow(
-                        () -> new CustomRuntimeException(ErrorCode.EXAM_APPLICATION_NOT_FOUND));
+        ExamApplicationNotifyProjection projection = loadExamApplication(targetId);
         return ApplicationGuestNotifyRequest.from(projection);

Add this helper (outside the selected range):

private ExamApplicationNotifyProjection loadExamApplication(Long targetId) {
    return examApplicationRepository.findExamAndPaymentByExamApplicationId(targetId)
            .orElseThrow(() -> new CustomRuntimeException(ErrorCode.EXAM_APPLICATION_NOT_FOUND));
}

Optionally update createApplicationVariable(...) to use loadExamApplication(targetId) as well.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9031145 and b51ec27.

📒 Files selected for processing (6)
  • src/main/java/life/mosu/mosuserver/application/notify/NotifyVariableFactory.java (3 hunks)
  • src/main/java/life/mosu/mosuserver/application/notify/dto/ApplicationGuestNotifyRequest.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/virtualaccount/event/DepositSuccessEventHandler.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/infra/notify/component/luna/LunaNotifyWithSmsFallbackSender.java (2 hunks)
  • src/main/java/life/mosu/mosuserver/infra/notify/dto/luna/LunaNotificationStatus.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/infra/notify/dto/luna/LunaNotifyTemplateCode.java (1 hunks)
🔇 Additional comments (6)
src/main/java/life/mosu/mosuserver/infra/notify/dto/luna/LunaNotifyTemplateCode.java (1)

14-18: Validation complete: New Luna template registration is correct

  • Template ID 50051 is unique in LunaNotifyTemplateCode.java (no duplicates found).
  • Message keys notify.exam.guest.application.complete.alimtalk (line 19) and notify.exam.guest.application.complete.sms (line 26) exist in src/main/resources/messages_ko.properties.

No further action required.

src/main/java/life/mosu/mosuserver/application/notify/NotifyVariableFactory.java (1)

43-44: LGTM: Guest application status wiring

The new APPLICATION_GUEST_SUCCESS branch is correctly added and routed to a dedicated variable builder.

src/main/java/life/mosu/mosuserver/application/virtualaccount/event/DepositSuccessEventHandler.java (1)

42-44: Branch Notification Status Based on Application Type

The handler currently uses APPLICATION_GUEST_SUCCESS unconditionally, which will send the guest template for all deposits. Since ExamApplicationJpaEntity has no isGuest or applicationType field, please verify how to distinguish guest vs. regular applications in your domain model (e.g., via a service call or a newly added flag) and then update the code accordingly:

File: src/main/java/life/mosu/mosuserver/application/virtualaccount/event/DepositSuccessEventHandler.java
Lines: ~42–44

Suggested change (replace exam.isGuest() with your actual predicate):

-        LunaNotificationEvent lunaNotificationEvent = LunaNotificationEvent.create(
-                LunaNotificationStatus.APPLICATION_GUEST_SUCCESS,
-                exam.getUserId(), exam.getId());
+        // TODO: apply the correct guest check here
+        LunaNotificationStatus status = exam.isGuest()
+                ? LunaNotificationStatus.APPLICATION_GUEST_SUCCESS
+                : LunaNotificationStatus.APPLICATION_SUCCESS;
+        LunaNotificationEvent lunaNotificationEvent = LunaNotificationEvent.create(
+                status,
+                exam.getUserId(), exam.getId());

Please confirm which property or service call indicates a guest application and adjust the branching logic accordingly.

src/main/java/life/mosu/mosuserver/infra/notify/dto/luna/LunaNotificationStatus.java (1)

11-12: LGTM: New status aligns with template code and success semantics

The new APPLICATION_GUEST_SUCCESS status is correctly defined and follows the existing constructor path (SUCCESS).

src/main/java/life/mosu/mosuserver/infra/notify/component/luna/LunaNotifyWithSmsFallbackSender.java (2)

3-3: LGTM: Status imported and mapped

Static import added for APPLICATION_GUEST_SUCCESS matches the mapping below.


27-27: LGTM: Sender now covers guest application completion

Including APPLICATION_GUEST_SUCCESS in the strategy mapping ensures proper routing through the SMS-fallback sender.

@polyglot-k polyglot-k merged commit 54683b4 into develop Aug 12, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants